/**
 * 
 */
package com.hera.process.config.dao;

import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.hera.base.util.WrapperDate;

import com.hera.base.util.JdbcTemplateUtil;

/**
 * @author cmontes
 *
 */
@Repository("jdbcCoreDao")
public class JdbcOracleCoreDao implements JdbcCoreDao{

	static final Logger logger = Logger.getLogger(JdbcOracleCoreDao.class);
	
	@Autowired(required=true)
	//JdbcTemplateUtil jdbcTemplateUtil;
	JdbcTemplate jdbcTemplate;
	
	@SuppressWarnings("rawtypes")
	public Long insert(Map<String, Object> entity, String schema, String tableName){
		
		StringBuffer strFields = new StringBuffer();		
		StringBuffer strValues = new StringBuffer();
		Object[] values = new Object[entity.size() + 1];
		int contValues = 0;
		//JdbcTemplate jdbcTemplate = jdbcTemplateUtil.getJdbcTemplate("java:/comp/env/jdbc/WORKFLOW2");
		Long identity = jdbcTemplate.queryForLong("SELECT "+schema+".SEQ_"+tableName+".NEXTVAL FROM DUAL");
		values[contValues++] = identity;	
		Iterator entries = entity.entrySet().iterator();
		while (entries.hasNext()) {
		    Map.Entry entry = (Map.Entry)entries.next();
		    
		    strFields.append(entry.getKey());
		    strValues.append("?");
		    if(entry.getValue() instanceof WrapperDate ){
		    	values[contValues++] = ((WrapperDate)entry.getValue()).getValue();
		    }else if (entry.getValue() instanceof LinkedHashMap ){
		    	values[contValues++] = new Date((Long)((LinkedHashMap)entry.getValue()).get("value"));
		    }else{
		    	values[contValues++] = entry.getValue();
		    }
		    if(entries.hasNext()){
		    	 strFields.append(", ");
		    	 strValues.append(", ");		    	 
		    }
		}
		
		StringBuffer strQuery = new StringBuffer();
		strQuery.append("insert into ").append(schema).append(".").append(tableName);
		strQuery.append(" ( ID, ");
		strQuery.append(strFields);
		strQuery.append(" ) ");
		//strQuery.append("values ( ").append(schema).append(".SEQ_").append(tableName).append(".NEXTVAL, ");
		strQuery.append("values ( ?, ");
		strQuery.append(strValues);
		strQuery.append(" ) ");
	
		logger.debug(strQuery.toString());
		
		//JdbcTemplate jdbcTemplate = jdbcTemplateUtil.getJdbcTemplate("java:/comp/env/jdbc/WORKFLOW2");
		jdbcTemplate.update(strQuery.toString(), values);
		
		return identity;
	}
	
	@SuppressWarnings("rawtypes")
	public void updateById(Long identity, Map<String, Object> entity, String schema, String tableName){
		
		StringBuffer strFields = new StringBuffer();
		Object[] values = new Object[entity.size() + 1];
		int contValues = 0;
		Iterator entries = entity.entrySet().iterator();
		while (entries.hasNext()) {
		    Map.Entry entry = (Map.Entry)entries.next();
		    
		    strFields.append(entry.getKey());
		    strFields.append("= ?");
		    
		    if(entry.getValue() instanceof WrapperDate ){
		    	values[contValues++] = ((WrapperDate)entry.getValue()).getValue();
		    }else if (entry.getValue() instanceof LinkedHashMap ){
		    	values[contValues++] = new Date((Long)((LinkedHashMap)entry.getValue()).get("value"));		    	
		    }else{
		    	values[contValues++] = entry.getValue();
		    }
		    if(entries.hasNext()){
		    	 strFields.append(", ");
		    }
		}
		values[contValues++] = identity;
		
		StringBuffer strQuery = new StringBuffer();
		strQuery.append("update ").append(schema).append(".").append(tableName);
		strQuery.append(" set ");
		strQuery.append(strFields);
		strQuery.append(" where ");
		strQuery.append(" ID = ? ");
		logger.debug(strQuery.toString());
		
		//JdbcTemplate jdbcTemplate = jdbcTemplateUtil.getJdbcTemplate("java:/comp/env/jdbc/WORKFLOW2");
		jdbcTemplate.update(strQuery.toString(), values);
	}
	
	public void deleteById(Long identity, String schema, String tableName){
		StringBuffer strQuery = new StringBuffer();
		strQuery.append("delete from ").append(schema).append(".").append(tableName);
		strQuery.append(" where ID = ? ");
		logger.debug(strQuery.toString());
		
		//JdbcTemplate jdbcTemplate = jdbcTemplateUtil.getJdbcTemplate("java:/comp/env/jdbc/WORKFLOW2");
		jdbcTemplate.update(strQuery.toString(), identity);
	}
	
	public Map<String, Object> selectById(Long identity, List<Object> arrFields, String schema, String tableName){
		StringBuffer strFields = new StringBuffer();
		for(int i=0; i<arrFields.size(); i++){
			strFields.append(arrFields.get(i));
			if(i < arrFields.size() - 1 ){
		    	 strFields.append(", ");    	 
		    }
		}
		
		StringBuffer strQuery = new StringBuffer();
		strQuery.append("select ");
		strQuery.append(strFields.toString());
		strQuery.append(" from ").append(schema).append(".").append(tableName);
		strQuery.append(" where ID = ? ");
		logger.debug(strQuery.toString());

		//JdbcTemplate jdbcTemplate = jdbcTemplateUtil.getJdbcTemplate("java:/comp/env/jdbc/WORKFLOW2");
		return jdbcTemplate.queryForMap(strQuery.toString(), identity);
	}
	
	public List<Map<String, Object>> selectList(String where, String[] arrFields, Object[] params, String schema, String tableName){
		
		StringBuffer strFields = new StringBuffer();
		for(int i=0; i<arrFields.length; i++){
			strFields.append(arrFields[i]);
			if(i < arrFields.length - 1 ){
		    	 strFields.append(", ");    	 
		    }
		}
		
		StringBuffer strQuery = new StringBuffer();
		strQuery.append("select ");
		strQuery.append(strFields.toString());
		strQuery.append(" from ").append(schema).append(".").append(tableName);
		strQuery.append(" where ");
		strQuery.append(where);
		logger.debug(strQuery.toString());

		//JdbcTemplate jdbcTemplate = jdbcTemplateUtil.getJdbcTemplate("java:/comp/env/jdbc/WORKFLOW2");
		return jdbcTemplate.queryForList(strQuery.toString(), params);
	}
	
	/*
	public static void main(String[] args){
		Map<String, Object> entity = new HashMap<String, Object>();
		entity.put("NOMBRE", "CRISTIAN");
		entity.put("APEPAT", "MONTES");
		entity.put("TIPODOC", "001");
		entity.put("NRODOC", "40737329");
		entity.put("EDAD", new Integer(34));
		entity.put("PRECIO", new Double(56.9));
		
		String[] arrFields = new String[4];
		arrFields[0] = "NOMBRE";
		arrFields[1] = "TIPODOC";
		arrFields[2] = "EDAD";
		arrFields[3] = "PRECIO";
		
		JdbcOracleCoreDao jdbcOracleCoreDao = new JdbcOracleCoreDao();
		jdbcOracleCoreDao.insert(entity, "PROFIN", "TBL_CLIENTE");
		jdbcOracleCoreDao.updateById(50l, entity, "PROFIN", "TBL_CLIENTE");
		jdbcOracleCoreDao.deleteById(50l, "PROFIN", "TBL_CLIENTE");
		jdbcOracleCoreDao.selectById(50l, arrFields, "PROFIN", "TBL_CLIENTE");
		jdbcOracleCoreDao.selectList("abc = ? and mmm = ? ", arrFields, "PROFIN", "TBL_CLIENTE");
	}*/

}
